Stochastic Block model for bipartite graphs

A work around to generate a bipartite graph with different community structures in R/Python using SBM from the igraph package.

For python there is an equivalent function SBMhttps://igraph.org/python/api/latest/igraph._igraph.GraphBase.html#SBM other igraph functions https://igraph.org/python/api/latest/igraph.Graph.html, or the multilevel community detection https://igraph.org/python/api/latest/igraph.Graph.html#community_multilevel.

How to use SBM to generate bipartite graphs with community structure.

Undirected and Unweighted Bipartite Network with two communities and two modes (bipartite).

require(igraph)

nv <- 100 #nodes
nc <- 2 #comm
nb <- 2 * nc #blocks

#Number of nodes in each community and mode.
Com1_Mod1_nv <- 20 #nodes in community 1 that belong to mode 1.
Com1_Mod2_nv <- 10
Com2_Mod1_nv <- 40
Com2_Mod2_nv <- 30
sizes  <-  c(Com1_Mod1_nv,Com1_Mod2_nv,Com2_Mod1_nv,Com2_Mod2_nv)

Com1p <- 0.4  #Probability  of connection between nodes in community one.
Com2p <- 0.4  #Probability  of connection between nodes in community two.
p <- 0.01 #General probability of connection  betwen nodes in differnt commmunities.

community_prob <- matrix(nrow=nb, ncol=nb,0)
rownames(community_prob) <- c("Com1_Mod1","Com1_Mod2","Com2_Mod1","Com2_Mod2")
colnames(community_prob) <- c("Com1_Mod1","Com1_Mod2","Com2_Mod1","Com2_Mod2")
community_prob[1,2] <-  Com1p
community_prob[3,4] <-  Com2p

community_prob[1,4] <-  p
community_prob[2,3] <-  p

community_prob <- (community_prob+t(community_prob))

The resulting probability of connection between nodes of different blocks

community_prob
##           Com1_Mod1 Com1_Mod2 Com2_Mod1 Com2_Mod2
## Com1_Mod1      0.00      0.40      0.00      0.01
## Com1_Mod2      0.40      0.00      0.01      0.00
## Com2_Mod1      0.00      0.01      0.00      0.40
## Com2_Mod2      0.01      0.00      0.40      0.00

Generation of the graph via sample_sbm.

bipG <- sample_sbm(nv,community_prob,sizes,directed = FALSE,loops = FALSE)

Modes <- c(rep(1,Com1_Mod1_nv),rep(2,Com1_Mod2_nv),rep(1,Com2_Mod1_nv),rep(2,Com2_Mod2_nv))
Coms <- c(rep(1,Com1_Mod1_nv+Com1_Mod2_nv),rep(2,Com2_Mod1_nv+Com2_Mod2_nv))

bipG
## IGRAPH c9b1330 U--- 100 607 -- Stochastic block-model
## + attr: name (g/c), loops (g/l)
## + edges from c9b1330:
##  [1]  1--21  2--21  3--21  7--21  8--21 10--21 16--21 17--21 18--21 19--21
## [11] 20--21  2--22  3--22  4--22  7--22 11--22 12--22 15--22 17--22 19--22
## [21]  2--23  4--23  5--23  7--23  9--23 13--23 16--23  1--24  4--24  8--24
## [31]  9--24 10--24 13--24 14--24 17--24 18--24  1--25  2--25  5--25  6--25
## [41]  7--25  8--25  9--25 11--25 14--25 20--25  5--26  8--26 10--26 11--26
## [51] 14--26 17--26 18--26 20--26  2--27  5--27  8--27 10--27 11--27 12--27
## [61] 13--27 14--27 16--27 18--27  2--28  3--28  6--28  8--28 10--28 14--28
## [71] 15--28 18--28 19--28 20--28  1--29  2--29  3--29  9--29 10--29 15--29
## + ... omitted several edges

Plotting accorrding to mode or community

Note that the nodes in the graph are ordered according the block order in community_prob, i.e. c("Com1_Mod1","Com1_Mod2","Com2_Mod1","Com2_Mod2").

col<-c("red","blue")
Shape<- c("circle", "square")
plot(bipG,vertex.color= col[Coms], vertex.shape=Shape[Modes],vertex.size=8)

plot(bipG,vertex.color= col[Coms], vertex.shape=Shape[Modes],layout = layout_as_bipartite(bipG,types = Modes==1),edge.curve=TRUE,vertex.size=5,vertex.cex=1)

adj <- get.adjacency(bipG)